/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

import { useHistory, useLocation } from '@docusaurus/router';
import { CopyrightNotice, RecommendationNotice, sortedUsers, TagList, Tags } from '@site/src/data/users';
import Layout from '@theme/Layout';
import clsx from 'clsx';
import React, { useEffect, useMemo, useState } from 'react';
import ShowcaseCard from './_components/ShowcaseCard';
import ShowcaseTagSelect, { readSearchTags } from './_components/ShowcaseTagSelect';
import styles from './styles.module.css';

type UserState = {
  scrollTopPosition: number;
  focusedElementId: string | undefined;
};

function restoreUserState(userState: UserState | null) {
  const { scrollTopPosition, focusedElementId } = userState ?? {
    scrollTopPosition: 0,
    focusedElementId: undefined,
  };
  if (focusedElementId) {
    document.getElementById(focusedElementId)?.focus();
  }
  window.scrollTo({ top: scrollTopPosition });
}

const SearchNameQueryKey = 'name';

function readSearchName(search: string) {
  return new URLSearchParams(search).get(SearchNameQueryKey);
}

function ShowcaseHeader() {
  return (
    <section className="margin-top--lg margin-bottom--lg text--center">
      <h1>开发者工具下载</h1>
      <p>这里收集了一些开发者常用的工具软件，方便快速下载使用</p>
    </section>
  );
}

function ShowcaseFilters() {
  const location = useLocation();
  const history = useHistory();
  const [searchInput, setSearchInput] = useState<string>('');
  const [value, setValue] = useState<string | null>(null);

  useEffect(() => {
    const searchValue = readSearchName(location.search);
    setValue(searchValue);
    setSearchInput(searchValue || '');
  }, [location]);

  const handleSearch = () => {
    const newSearch = new URLSearchParams(location.search);
    newSearch.delete(SearchNameQueryKey);
    if (searchInput.trim()) {
      newSearch.set(SearchNameQueryKey, searchInput);
    }
    history.push({
      ...location,
      search: newSearch.toString(),
    });
  };

  const handleKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === 'Enter') {
      handleSearch();
    }
  };

  return (
    <section className="container margin-top--lg margin-bottom--lg">
      <div className={styles.filterHeader}>
        <h2>筛选工具</h2>
        <div className={styles.searchContainer}>
          <input
            id="searchbar"
            placeholder="搜索工具名称... (按回车搜索)"
            value={searchInput}
            onChange={(e) => setSearchInput(e.target.value)}
            onKeyPress={handleKeyPress}
          />
        </div>
      </div>
      <ul className={clsx('clean-list', styles.checkboxList)}>
        {TagList.map((tag, i) => {
          const { label, description, color } = Tags[tag];
          const id = `showcase_checkbox_id_${tag}`;

          return (
            <li key={i} className={styles.checkboxListItem}>
              <ShowcaseTagSelect
                tag={tag}
                label={label}
                icon={
                  <span
                    style={{
                      backgroundColor: color,
                      width: 10,
                      height: 10,
                      borderRadius: '50%',
                      marginLeft: 8,
                    }}
                  />
                }
                description={description}
              />
            </li>
          );
        })}
      </ul>
    </section>
  );
}

function filterUsers(users: typeof sortedUsers, selectedTags: string[], searchName: string | null) {
  if (searchName) {
    users = users.filter((user) =>
      user.title.toLowerCase().includes(searchName.toLowerCase()),
    );
  }
  if (selectedTags.length === 0) {
    return users;
  }
  return users.filter((user) => {
    if (user.tags.length === 0) {
      return false;
    }
    return selectedTags.some((tag) => user.tags.includes(tag));
  });
}

function useFilteredUsers() {
  const location = useLocation<UserState>();
  const [selectedTags, setSelectedTags] = useState<string[]>([]);
  const [searchName, setSearchName] = useState<string | null>(null);

  useEffect(() => {
    setSelectedTags(readSearchTags(location.search));
    setSearchName(readSearchName(location.search));
    restoreUserState(location.state);
  }, [location]);

  return useMemo(
    () => filterUsers(sortedUsers, selectedTags, searchName),
    [selectedTags, searchName],
  );
}

export default function Showcase(): JSX.Element {
  const filteredUsers = useFilteredUsers();

  return (
    <Layout title="软件下载" description="开发者常用软件下载">
      <main>
        <ShowcaseHeader />
        <ShowcaseFilters />
        <div className="container margin-top--lg margin-bottom--lg">
          {filteredUsers.length > 0 ? (
            <div className={styles.showcaseContainer}>
              <ul className={styles.showcaseList}>
                {filteredUsers.map((user) => (
                  <ShowcaseCard key={user.key} user={user} />
                ))}
              </ul>
            </div>
          ) : (
            <div className={styles.showcaseEmpty}>
              <h2>未找到相关软件</h2>
            </div>
          )}
        </div>
        {RecommendationNotice}
        <div style={{
          textAlign: 'center',
          fontSize: '0.8rem',
          color: 'var(--ifm-color-emphasis-600)',
          padding: '2rem 1rem',
          borderTop: '1px solid var(--ifm-color-emphasis-200)',
          marginTop: '2rem',
        }}>
          {CopyrightNotice}
        </div>
      </main>
    </Layout>
  );
}
